﻿using System;
using System.ComponentModel;
using System.Web.UI;


namespace Guru.Web.Controls.Validators
{
    /// <summary>
    /// Generate jQuery code base on basic jQuery rule
    /// List of rule:
    ///     None,
    ///     Required,
    ///     Minlength,
    ///     Maxlength,
    ///     Rangelength,
    ///     Min,
    ///     Max,
    ///     Range,
    ///     Email,
    ///     Url,
    ///     Number,
    ///     Digits,
    ///     Accept,
    ///     EqualTo
    /// </summary>
    public class BasicValidationItem: ValidationItem
    {
        #region const       
        /// <summary>
        /// jQuery custom message
        ///     {0}: Name of rule
        ///     {1}: Message
        /// </summary>
        protected const string _JS_MESSAGE = "{0}: \"{1}\"";

        /// <summary>
        /// Add rule
        ///     {0}:ClientID of the control
        ///     {1}: Name of the rule
        ///     {2}: Value of the rule
        ///     {3}: Custom message
        /// </summary>
        protected const string _JS_RULE = @"
            if($('#{0}') != null)           
                $('#{0}').rules('add', [OPEN]
                    {1}: {2},
                     messages: [OPEN]
                        {3}
                    [CLOSE]
                [CLOSE]); 
                ";
        #endregion

        #region Init
        public BasicValidationItem() : base() {
            Rule = ValidationRule.None;
        }
        public BasicValidationItem(string controlToValidateId, string message, string validdationGroups, ValidationRule rule)
            : base(controlToValidateId, message)
        {
            Rule = rule;
        }

        #endregion

        #region Properties

        /// <summary>
        /// A validation rule associates an element with a validation method, 
        /// like "validate input with name "primary-mail" with methods "required" and "email". 
        /// </summary>
        [Category("Behavior"), DefaultValue(""),
        Description("A validation rule associates an element"), NotifyParentProperty(true)]
        public ValidationRule Rule
        {
            set { ViewState["Rule"] = value; }
            get
            {
                object obj = ViewState["Rule"];
                if (obj == null) throw new PropertyNullRefException("Rule");
                else return (ValidationRule)obj;
            }
        }

        /// <summary>
        /// Minimum number of characters allowed in the input control
        /// The MinLength will not take affect until Rule=MinLength or RangeLength
        /// </summary>
        [Category("Behavior"), DefaultValue(""),
        Description("Minimum number of characters allowed in the input control"), NotifyParentProperty(true)]
        public int MinLength
        {
            set
            {
                ViewState["MinLength"] = value;
            }
            get
            {
                object minlength=ViewState["MinLength"];
                if (minlength == null) throw new PropertyNullRefException("MinLength");
                return int.Parse(minlength.ToString());
            }
        }


        /// <summary>
        /// Maximum number of characters allowed in the input control
        /// The MaxLength will not take affect until Rule=MaxLength or RangeLength
        /// </summary>
        [Category("Behavior"), DefaultValue(""),
        Description("Maximum number of characters allowed in the input control"), NotifyParentProperty(true)]
        public int MaxLength
        {
            set
            {
                ViewState["MaxLength"] = value;
            }
            get
            {
                object maxLength = ViewState["MaxLength"];
                if (maxLength == null) throw new PropertyNullRefException("MaxLength");
                return int.Parse(maxLength.ToString());
            }
        }

        /// <summary>
        /// Represents the smallest posible value of an input data
        /// The MinValue will not take affect until Rule=Min or Range
        /// </summary>
        [Category("Behavior"), DefaultValue(""),
        Description("Represents the smallest posible value of an input data"), NotifyParentProperty(true)]
        public float MinValue
        {
            set
            {
                ViewState["MinValue"] = value;
            }
            get
            {
                object minValue = ViewState["MinValue"];
                if (minValue == null) throw new PropertyNullRefException("MinValue");
                return float.Parse(minValue.ToString());
            }
        }      
        
        /// <summary>
        /// Represents the largest posible value of an input data
        /// The MaxValue will not take affect until Rule=Max or Range
        /// </summary>
        [Category("Behavior"), DefaultValue(""),
        Description("Represents the largest posible value of an input data"), NotifyParentProperty(true)]
        public float MaxValue
        {
            set
            {
                ViewState["MaxValue"] = value;
            }
            get
            {
                object maxValue = ViewState["MaxValue"];
                if (maxValue == null) throw new PropertyNullRefException("MaxValue");
                return float.Parse(maxValue.ToString());
            }
        }

        /// <summary>
        /// The allowed file extensions, seperated via "|" (or a comma, ","), defaults to "png|jpe?g|gif"
        /// The Extensions will not take affect until Rule=Accept
        /// </summary>
        [Category("Behavior"), DefaultValue(""),
        Description("The allowed file extensions, seperated via '|' (or a comma, ','), defaults to 'png|jpeg|gif'"), NotifyParentProperty(true)]
        public string Extensions
        {
            set
            {
                ViewState["Extensions"] = value;
            }
            get
            {
                if (ViewState["Extensions"]==null) throw new PropertyNullRefException("Extensions");
                return (string)ViewState["Extensions"];
            }
        }

        /// <summary>       
        /// The Pattern will not take affect until Rule=StringAccept, StringUnaccept
        /// </summary>
        [Category("Behavior"), DefaultValue(""),
        Description("Pattern"), NotifyParentProperty(true)]
        public string Pattern
        {
            set
            {
                ViewState["Pattern"] = value;
            }
            get
            {
                if (ViewState["Pattern"] == null) throw new PropertyNullRefException("Pattern");
                return (string)ViewState["Pattern"];
            }
        }
        #endregion

        #region Redering
        public override string RenderTrigger(HtmlTextWriter writer)
        {
            return string.Empty;
        }

        public override string RenderRuleRegister(HtmlTextWriter writer)
        {
            string ruleValue = this.ToRuleValue();
            string rule = this.ToRuleName();
            string message = string.Empty;
            if (string.IsNullOrEmpty(this.Message) == false)
                message = string.Format(_JS_MESSAGE, rule, this.Message);
            string basicRule = string.Format(_JS_RULE, this.ObjectControlToValidate.ToJQueryId(), rule, ruleValue, message);
            return basicRule.ReplaceTag();
        }

        public BasicValidationItem Clone()
        {
            BasicValidationItem item = new BasicValidationItem();
            item.Container = this.Container;
            if (ViewState["ControlToValidateID"] != null)
                item.ControlToValidateID = this.ControlToValidateID;
            if (ViewState["Extensions"] != null)
                item.Extensions = this.Extensions;
            if (ViewState["MaxLength"] != null)
                item.MaxLength = this.MaxLength;
            if (ViewState["MaxValue"] != null)
                item.MaxValue = this.MaxValue;
            if (ViewState["Message"] != null)
                item.Message = this.Message;
            if (ViewState["MinLength"] != null)
                item.MinLength = this.MinLength;
            if (ViewState["MinValue"] != null)
                item.MinValue = this.MinValue;
            if (ViewState["Pattern"] != null)
                item.Pattern = this.Pattern;
            if (ViewState["ResMessage"] != null)
                item.ResMessage = this.ResMessage;
            if (ViewState["ResParams"] != null)
                item.ResParams = this.ResParams;
            if (ViewState["Rule"] != null)
                item.Rule = this.Rule;

            return item;
        }
      
        #endregion

       
    }
}
